import 'dart:convert';
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:sqflite/sqflite.dart';
import 'dart:async';

StreamController logController = StreamController<String>.broadcast();

class Log {
  static final Log _instance = Log._internal();
  static bool disable = false;
  late Database _db;

  //然后修改构造方法，提供了一个工厂方法获取该类的实例,将实例对象对应的方法返回出去
  factory Log() {
    return _instance;
  }
  Log._internal() {
    if (disable) return;
    //此处进行初始化操作
    getDatabasesPath().then((databasePath) {
      File(databasePath + '/logs/log.db').exists().then((value) {
        openDatabase(databasePath + '/logs/log.db').then((value) {
          _db = value;
          value
              .execute(
                  "CREATE TABLE IF NOT EXISTS network_log(id INTEGER PRIMARY KEY AUTOINCREMENT, url TEXT,request_header TEXT, method TEXT, request_body TEXT, response_body TEXT, response_header TEXT, status_code INTEGER, time INTEGER)")
              .catchError((error) {});

          value.execute(
              "CREATE TABLE IF NOT EXISTS error_log(id INTEGER PRIMARY KEY AUTOINCREMENT, error_doc TEXT,web_url TEXT, create_time TEXT, error_type TEXT, error_env TEXT, time INTEGER)");
        });
      });
    });
  }
  Future<List<Map>> logs() async {
    final List<Map<String, dynamic>> maps = await _db.query('users');
    return maps;
  }

  insertNetWork(Response response) async {
    if (disable) return;
    List ignoreUrl = ["/log/add"];
    if (ignoreUrl.contains(response.requestOptions.path)) return;
    Map data = response.requestOptions.data ?? {};
    Map queryParameters = response.requestOptions.queryParameters;

    Map<String, dynamic> item = {
      'url': response.requestOptions.path,
      'request_header': "${response.requestOptions.headers}",
      'response_header': "${response.headers}",
      'method': response.requestOptions.method,
      'request_body': data.isEmpty ? queryParameters : data,
      // 'request_body': jsonEncode({
      //   ...response.requestOptions.queryParameters,
      //   ...response.requestOptions.data
      // }),
      'response_body': jsonEncode(response.data ?? ""),
      'status_code': response.statusCode,
      'time': DateTime.now().millisecondsSinceEpoch,
    };
    _db.insert('network_log', item);
    logController.sink.add("${response.statusCode}");
  }

  insertErrorNetWork(DioError response) async {
    if (disable) return;
    Map data = response.requestOptions.data ?? {};
    Map queryParameters = response.requestOptions.queryParameters;
    Map<String, dynamic> item = {
      'url': response.requestOptions.path,
      'request_header': "${response.requestOptions.headers}",
      'response_header': "${response.response?.headers}",
      'method': response.requestOptions.method,
      'request_body': data.isEmpty ? queryParameters : data,
      'response_body': jsonEncode(response.response?.data),
      'status_code': response.response?.statusCode,
      'time': DateTime.now().millisecondsSinceEpoch,
    };
    _db.insert('network_log', item);
    logController.sink.add("${response.response?.statusCode}");
  }

  Future<int> cleanNetWorkLog() {
    return _db.delete('network_log');
  }

  Future<int> cleanErrorLog() {
    return _db.delete('error_log');
  }

  Future<List<Map<String, dynamic>>> fetchNetWorkPagedData(
      {required int page, int pageSize = 30}) async {
    // 计算起始索引
    int startIndex = page * pageSize;

    // 分页查询SQL语句
    String sql =
        'SELECT * FROM network_log ORDER BY time DESC LIMIT ? OFFSET ?';

    // 执行查询
    final List<Map<String, dynamic>> list =
        await _db.rawQuery(sql, [pageSize, startIndex]);
    return list;
  }

  insertErrorLog(Map errorData) async {
    if (disable) return;
    if (errorData["webUrl"] == '/log') return;
    Map<String, dynamic> item = {
      "web_url": errorData["webUrl"],
      "error_doc": errorData["errorDoc"],
      "error_type": 'stackTrace',
      // "error_env": '${Config.env}',
      'time': DateTime.now().millisecondsSinceEpoch,
    };
    _db.insert('error_log', item);
  }

  Future<List<Map<String, dynamic>>> fetchErrorPagedData(
      {required int page, int pageSize = 30}) async {
    // 计算起始索引
    int startIndex = page * pageSize;

    // 分页查询SQL语句
    String sql = 'SELECT * FROM error_log ORDER BY time DESC LIMIT ? OFFSET ?';

    // 执行查询
    final List<Map<String, dynamic>> list =
        await _db.rawQuery(sql, [pageSize, startIndex]);

    return list;
  }
}
